/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#include "JoystickControlSettingsHandler.h"

#include <stdio.h>

JoystickControlSettingsHandler::JoystickControlSettingsHandler(
    gim::CSettings *aSettings,
    const std::vector< t_stringPair > &axisList,
    const std::vector< t_stringPair > &buttonList)
  : settings (aSettings),
    configStart ("GIMUI.JoystickControl")
{
  //TODO Do settings handling here.
  dPrint(2, "Initializing settings.");
  char intStr[32];
  int loopCount = 1;

  dPrint(ODTEST,"AxisList size is %d", axisList.size());
  dPrint(ODTEST,"ButtonList size is %d", buttonList.size());

  // Find Configuration1 2 3 etc. and get their names.
  if (settings != NULL) {
    settings->Lock();
    bool success = true;
    if (settings->SetBaseKey(configStart)) {
      do {
        snprintf(intStr, 30, "%d", loopCount);
        std::string keyString = "Configuration";
        keyString.append(intStr);
        //keyString.append(".configname");
        std::string name;
        success = settings->GetValue(keyString + ".configname", name);
        if (success) {
          dPrint(4, "Found configuration: %s, by key: '%s'", name.c_str(), 
                 std::string(keyString + ".configname").c_str());
          confNames.push_back(name);
          
          // Find axisselections
          t_axisConfigVector curAxisConfigList;
          int axisCount = 0;
          for(std::vector< t_stringPair >::const_iterator axisIter = axisList.begin();
              axisIter != axisList.end();
              ++axisIter)
          {
            std::string optionString = keyString;
            optionString.append(".");
            optionString.append(axisIter->first); // Component-name
            optionString.append(".Axes.");
            optionString.append(axisIter->second); // Axis-name
            std::string invertString = optionString;
            invertString.append(".invert");
            optionString.append(".axis");
            int axisNumber = -1;
            int axisInvert = 0;
            
            if (settings->GetValue(optionString, axisNumber)) {
              settings->GetValue(invertString, axisInvert);
              // Add axis to configuration list
              curAxisConfigList.push_back(AxisConfiguration(axisIter->first,
                  axisIter->second, axisNumber, axisInvert));
              dPrint(2, "Found axisconfig for component %s axis %s: %d, invert %d",
                     axisIter->first.c_str(), axisIter->second.c_str(), axisNumber, axisInvert);
              ++axisCount;
            } else {
              dPrint(2, "Did not find axisconfig %s", optionString.c_str());
            }
          }
          
          if (axisCount > 0) {
            dPrint(2, "Added %d axes to config %d", axisCount, loopCount);
            axisConfigList.insert(t_axisConfigMapPair(loopCount, curAxisConfigList));
          }
          
          // Find buttonselections
          t_buttonConfigVector curButtonConfigList;
          int buttonCount = 0;
          for(std::vector< t_stringPair >::const_iterator buttonIter = buttonList.begin();
              buttonIter != buttonList.end();
              ++buttonIter)
          {
            std::string optionString = keyString;
            optionString.append(".");
            optionString.append(buttonIter->first); // Component-name
            optionString.append(".Buttons.");
            optionString.append(buttonIter->second); // Axis-name
            optionString.append(".button");
            int buttonNumber = -1;
            
            if (settings->GetValue(optionString, buttonNumber)) {
              // Add button to configuration list
              curButtonConfigList.push_back(ButtonConfiguration(buttonIter->first,
                  buttonIter->second, buttonNumber));
              dPrint(2, "Found buttonconfig for component %s button %s: %d",
                     buttonIter->first.c_str(), buttonIter->second.c_str(), buttonNumber);
              ++buttonCount;
            } else {
              dPrint(2, "Did not find buttonconfig %s", optionString.c_str());
            }
          }
          
          if (buttonCount > 0) {
            dPrint(2, "Added %d button to config %d", buttonCount, loopCount);
            buttonConfigList.insert(t_buttonConfigMapPair(loopCount, curButtonConfigList));            
          }
          
        } else {
          dPrint(2, "Did not find key: %s", keyString.c_str());
        }
        ++loopCount;
      } while (success);
    } else {
      dPrint(1, "Did not find settings for %s", configStart.c_str());
    }
    
    settings->Unlock();
  } else {
    dPrint(2, "Settings-class was null!");
  }
}

JoystickControlSettingsHandler::~JoystickControlSettingsHandler()
{
  
}

int JoystickControlSettingsHandler::listConfigurations(
    std::vector<std::string> &configList)
{
  configList = confNames;
  return configList.size();
}

int JoystickControlSettingsHandler::listConfigurations(wxArrayString &configList)
{
  int n = 0;
  wxString configString;
  
  for (std::vector<std::string>::iterator iter = confNames.begin();
       iter != confNames.end();
       ++iter)
  {
    configList.Add(wxT(*iter));
    ++n;
  }
  
  return n;
}

int JoystickControlSettingsHandler::
listAxesForConfiguration(std::vector<AxisConfiguration> &axisConfigVector,
                         const int configId)
{
  dPrint(6, "Called with configId %d", configId);
  int result = 0;

  t_axisConfigMapConstIterator configIter = axisConfigList.find(configId+1);
  if (configIter != axisConfigList.end()) {
    axisConfigVector = configIter->second;
    result = axisConfigVector.size();
  } else {
    dPrint(2, "Did not find configuration %d", configId+1);
  }
  
  return result;
}

int JoystickControlSettingsHandler::listButtonsForConfiguration(
    std::vector<ButtonConfiguration> &buttonConfigVector,
    const int configId)
{
  dPrint(6, "Called with configId %d", configId);
  int result = 0;
  
  t_buttonConfigMapConstIterator configIter = buttonConfigList.find(configId+1);
  if (configIter != buttonConfigList.end()) {
    buttonConfigVector = configIter->second;
    result = buttonConfigVector.size();
  } else {
    dPrint(2, "Did not find configuration %d", configId+1);
  }
  
  return result;
}
